#include <iostream>
#include <string>
#include <cstring>
#include <cstdlib>
#include <stdio.h>
#include <unistd.h>



#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h> 

#include <signal.h>

#include "Comm.hpp"
#include "Log.hpp"

#define Retry 5
using namespace std;

bool visitServer(const string& serverip,uint16_t &serverport,int* cnt)
{
    bool ret = true;
    string funcbuffer;//用在了53行
    string inbuffer;
    ssize_t n,m;
    char server_list[1024];



    //1. 创建套接字socket
    int sockfd = socket(AF_INET,SOCK_STREAM,0);
    if(sockfd < 0)
    {
        cout << "sock errorr" << endl;
        return false;
    }

//2. connect
//不用bind ， 系统在local的时候会自动bind
    struct sockaddr_in local;
    memset(&local,0,sizeof(local));
    local.sin_family = AF_INET;
    local.sin_port = htons(serverport);
    //p（进程）: process 、n（网络）----不准确，但易记忆 
    inet_pton(AF_INET,serverip.c_str(),&local.sin_addr);

    int n1 = connect(sockfd,CONV(&local),sizeof(local));
    if(n1 < 0)
    {
        cout << "connect errorr" << endl;
        ret = false;
        goto END;
    }
//connect成功够将cnt置回1

    
    m = read(sockfd,server_list,sizeof(server_list));//直接使用sockfd
    if(m > 0)
    {
        server_list[m] = 0;
        cout << "服务器提供的服务：" <<  server_list << endl;
    }

    *cnt = 1;

    cout << "选择服务# ";
    getline(cin,funcbuffer);
    write(sockfd,funcbuffer.c_str(),funcbuffer.size());//直接使用sockfd

    cout << "Enter> ";
    getline(cin,inbuffer);
    if(inbuffer == "quit") 
    {
        return true;
    }

    n = write(sockfd,inbuffer.c_str(),inbuffer.size());//直接使用sockfd
    if(n > 0)
    {
        char buffer[1024];
        ssize_t m = read(sockfd,buffer,sizeof(buffer)-1);//直接使用sockfd
        if(m > 0)
        {
            buffer[m] = 0;//将最后位置写个0，作为结束标志 
            cout << "get a echo message -> " << buffer << endl;
        }
        else if(m == 0)//无数据正常退出
        {
            return true;
        }
        else
        {
            ret = false;
            goto END;
        }
    }
    else
    {
        ret = false;
        goto END;
    }
END:
    close(sockfd);
    return ret;
}

int main(int argc , char*argv[])
{
    if(argc != 3)
    {
        cout << "Usag: \n\t"<< argv[0] << " " << "local_ip local_port \n" << endl;
        return Usage_Err;
    }

    string serverip = argv[1];
    uint16_t serverport = atoi(argv[2]);

    signal(SIGPIPE,SIG_IGN);//对传递回来的SIGPIPE信号不做处理

    int cnt = 1;
    while(cnt <= Retry)
    {
        bool ret = visitServer(serverip,serverport,&cnt);
        if(ret){
            break;
        } 
        else{
            sleep(1);       
            cout << "server offline,retry...,count: " << cnt << endl;
            cnt++;
        }
    }

    if(cnt >= Retry) cout << "offline" << endl;

    return 0;
}
